package com.beantools.factory.reflect;

import com.beantools.execption.ClassException;
import com.beantools.util.ArrayUtil;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Type;

import static com.beantools.util.ObjectUtil.isNull;

/**
 * 这是实现接口{@code ReflectFactory}的抽象类{@code AbstractReflectFactory}
 *
 * @author baoya
 * @version 1.1.0
 * @see CommonReflectFactory
 * @since 1.0
 */
public abstract class AbstractReflectFactory<T> implements ReflectFactory<T>, Serializable {

    private static final long serialVersionUID = 2179539069990669469L;

    /**
     * 这是普通的获取无参构造器的方法。
     *
     * @param clazz 当前类字面常量
     * @return 无参构造器{@code Constructor}
     * @throws IllegalArgumentException {@code clazz}为空，则报参数异常
     * @throws NullPointerException     如果javabean没有对外开放的构造器，则报出空指针异常
     */
    @Override
    public Constructor getNoArgsConstruct(Class<? extends T> clazz) throws IllegalArgumentException, NullPointerException, ClassException {
        if (isNull(clazz)) {
            throw new IllegalArgumentException("类字面不能为空");
        }
        Constructor<?>[] constructors = clazz.getConstructors();
        if (ArrayUtil.isEmpty(constructors)) {
            throw new NullPointerException("类" + clazz.getName() + "没有对外开放的构造器");
        }
        //        创建有默构造方法
        Constructor defaultConstruct = null;
        for (Constructor<?> constructor : constructors) {
            Type[] constructParameters = constructor.getParameterTypes();
            if (constructParameters.length == 0) {
                defaultConstruct = constructor;
                break;
            }
        }
        if (isNull(defaultConstruct)) {
            throw new ClassException("没有无参构造器，也就是默认构造器", clazz);
        }
        return defaultConstruct;
    }
}
